#include "UManage.h"

CUserManage* CUserManage::user_ = nullptr;
std::mutex g_lock;

CUserManage::CUserManage()
{
    db_ = nullptr;
    prediction_id = 0;
}

CUserManage::~CUserManage()
{
    if(db_)
        delete db_;
}

CUserManage* CUserManage::GetUserManage()
{
    if(user_ == nullptr){
        g_lock.lock();
        if(user_ == nullptr)
            user_ = new CUserManage;
        g_lock.unlock();
    }
    return user_;
}

bool CUserManage::Init()
{
    //初始化数据库
    db_ = new CDBManage;
    if(db_ == nullptr){
        printf("User Init false\n");
        return false;
    }

    db_->InitDB();

    //缓存用户信息
    std::unordered_map<int, std::vector<std::string>> res;
    if(db_->GetAllUser(res) == false){
        printf("UserManage Init false\n");
        return false;
    }
    auto it = res.begin();
    while(it != res.end()){
        UserInfo uinf;
        uinf.user_id_ = std::stoi((*it).second[0]);
        uinf.nickname_ = (*it).second[1];
        uinf.telnum_ = (*it).second[2];
        uinf.passwd_ = (*it).second[3];
        db_->ReturnFriend(uinf.user_id_, uinf.friend_id_);
        uinf.user_status_ = OFF_LINE;
        user_info_[std::stoi((*it).second[0])] = uinf;
        tel_map_[(*it).second[2]] = std::make_pair(std::stoi((*it).second[0]), (*it).second[3]);
        //注册时的分配的id
        prediction_id = std::max(prediction_id, uinf.user_id_);
        it++;
    }
    prediction_id++;
    PrintUser();
    return true;
}

void CUserManage::PrintUser()
{
    auto it = user_info_.begin();
    while(it != user_info_.end()){
        UserInfo uinf;
        uinf = (*it).second;
        std::cout<<uinf.user_id_<<" "<<uinf.nickname_<<" "
        <<uinf.telnum_<<" "<<uinf.passwd_<<std::endl;
        it++;
    }
}

int CUserManage::Register(std::string& nickname, std::string& telnum, std::string& passwd)
{
        /*
            1. 看该手机号是否已经被注册
            2. 没有被注册则向数据库中插入数据注册
        */

    db_lock_.lock();
    if(db_->CheckTel(telnum) == false){
        db_lock_.unlock();
        return -1;
    }

    if(db_->RegisterUser(nickname, telnum, passwd, prediction_id) == false){
        db_lock_.unlock();
        return -2;   
    }

    int u_id = prediction_id++;
    db_lock_.unlock();

    UserInfo uif;
    uif.nickname_ = nickname;
    uif.passwd_ = passwd;
    uif.telnum_ = telnum;
    uif.user_id_ = u_id;
    uif.user_status_ = ON_LINE;

    user_info_[u_id] = uif;
    tel_map_[telnum] = std::make_pair(u_id, passwd);

    return u_id;
}

int CUserManage::LoginCheck(std::string telnum, std::string passwd, int socket)
{
    /*
        1. 查看telnum是否为空
        2. 查看telnum对应的passwd是否正确
        3. 校验成功后，修改用户状态，维护套接字
    */
   
    if(tel_map_.find(telnum) == tel_map_.end() || passwd != tel_map_[telnum].second)
        return -1;
    
    //3.
    user_info_[tel_map_[telnum].first].user_status_ = ON_LINE;
    user_info_[tel_map_[telnum].first].tcp_socket_ = socket;

    return tel_map_[telnum].first;
}

//返回好友列表
bool CUserManage::ReturnFriend(int user_id, Json::Value& friend_arr)
{
    /*
        1. 查看是否有这个用户
        2. 组织json对象插入到json数组
    */

   // 1.
    if(user_info_.find(user_id) == user_info_.end())
        return false;
    
    for(auto uid : user_info_[user_id].friend_id_){
        Json::Value tmp;
        tmp["nickname"] = user_info_[uid].nickname_;
        tmp["fu_id"] = user_info_[uid].user_id_;
        friend_arr.append(tmp);
    }

    return true;
}

//用户是否在线，在线返回接收方的sock
int CUserManage::CheckUserStatus(int user_id, int send_id)
{
    if(user_info_[user_id].user_status_ == OFF_LINE || user_info_[send_id].user_status_ == OFF_LINE)
        return -1;
    
    return user_info_[send_id].tcp_socket_;
}

//用户是否在线，在线返回接收方的sock
int CUserManage::CheckUserStatus(std::string telnum)
{
    int uid = tel_map_[telnum].first;
    if(user_info_.find(uid) == user_info_.end() || user_info_[uid].user_status_ == OFF_LINE)
        return -1;
    
    return  user_info_[uid].tcp_socket_;
}

//获取用户信息
void CUserManage::GetUser(std::string telnum, UserInfo& ui)
{
    int uid = tel_map_[telnum].first;
    ui = user_info_[uid];
}

void CUserManage::GetUser(int uid, UserInfo& ui)
{
    ui = user_info_[uid];
}

//插入好友信息
int CUserManage::RenewFriendInfo(int user_id, int friend_id)
{
    user_info_[user_id].friend_id_.push_back(friend_id);
    user_info_[friend_id].friend_id_.push_back(user_id);

    db_->RenewFriendInfo(user_id, friend_id);
    db_->RenewFriendInfo(friend_id, user_id);

    return user_info_[friend_id].tcp_socket_;
}

//退出更新用户状态
void CUserManage::RenewUserStatus(int user_id)
{
    user_info_[user_id].user_status_ = OFF_LINE;
}